package com.familyigo.gdemo;

import java.util.HashMap;
import java.util.Objects;

/**
 * A specialized map for storing String-Boolean pairs with fluent API support.
 * Ensures type safety and provides clear exception messages.
 */
public class DefineMap extends HashMap<String, Boolean> {

    public DefineMap() {
        super();
    }

    /**
     * Creates a map with key-value pairs from parameters.
     *
     * @param params Alternating String keys and Boolean values
     * @throws IllegalArgumentException for invalid parameters
     */
    public DefineMap(Object... params) {
        processParameters(params);
    }

    /**
     * Processes parameters ensuring type safety and completeness.
     *
     * @throws IllegalArgumentException for invalid parameters
     */
    private void processParameters(Object... params) {
        Objects.requireNonNull(params, "Parameters cannot be null");

        if (params.length % 2 != 0) {
            throw new IllegalArgumentException("Odd number of parameters provided. Expected key-value pairs.");
        }

        for (int i = 0; i < params.length; i += 2) {
            Object key = params[i];
            Object value = params[i + 1];

            validateKey(key, i);
            validateValue(value, i + 1);

            super.put((String) key, (Boolean) value);
        }
    }

    private void validateKey(Object key, int position) {
        if (key == null) {
            throw new NullPointerException("Null key at position " + position);
        }
        if (!(key instanceof String)) {
            throw new IllegalArgumentException(
                    "Invalid key type at position " + position + ". Expected String, got " + key.getClass()
            );
        }
    }

    private void validateValue(Object value, int position) {
        if (value != null && !(value instanceof Boolean)) {
            throw new IllegalArgumentException(
                    "Invalid value type at position " + position + ". Expected Boolean, got " + value.getClass()
            );
        }
    }

    /**
     * Fluent method to add key-value pairs.
     *
     * @return this instance for chaining
     */
    public DefineMap add(String key, Boolean value) {
        super.put(key, value);
        return this;
    }

    /**
     * Fluent method to add multiple key-value pairs.
     *
     * @return this instance for chaining
     */
    public DefineMap add(Object... params) {
        processParameters(params);
        return this;
    }

    /**
     * Factory method for creating instances.
     */
    public static DefineMap build(Object... params) {
        return new DefineMap(params);
    }


}
